package pacificlms.Verifiable.Database;

import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.Connection;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import javax.swing.JOptionPane;
import pacificlms.Email.EmailManager;
import pacificlms.MasterConnection;
import pacificlms.Verifiable.*;
import pacificlms.LoggedMember;

/**
 * Member is a child of VerifiableObject dealing with Members
 * Since all fields are get/set they are not individually commented
 * @author Brian Hume
 */
public class Member extends VerifiableObject
{

    @Override
    public String TableName() {
        return "Member";
    }
    
    
    public static Member FindMember(String Username, String Password)
    {
        boolean Login = false;
        try
        {
            Member Find = new Member();
            Find.LibraryCardNumber(Username);
            Find.Password(Password);
            String SQL = Find.FindIdenticalSQL();
            
            Connection con = MasterConnection.getInstance();
            Statement stmt = con.createStatement();
            ResultSet RS = stmt.executeQuery(SQL);
            
            if(RS.next())
            {
                Find.FillFromResultSet(RS, RS.getMetaData());
                return Find;
            }
        }
        catch(Exception Ex)
        {
            return null;
        }
        return null;
    }
    
    public static boolean ValidateLogin(String Username, String Password)
    {
        if (Username == null || Username.equals(""))
            return false;
        if (Password == null || Password.equals(""))
            return false;
        
        Member Check = FindMember(Username, Password);
        
        if (Check != null)
        {
            LoggedMember.Set(Check);//will update side panel
            return true;
        }
        else
        {
            return false;
        }
    }
    
    public void SendPasswordEmail()
    {
        EmailManager.ForgotPasswordEmail(this);
    }
    
    
    
    private String LibraryCardNumber;
    @VerifyAnnotation(ApplicationName="Library Card #", DBName="LibraryCardNumber",  Type=TypeEnum.NUMERICSTRING, Length=12, ExactLength=true, Editable=false)
    public String LibraryCardNumber(String value)
    {
        return LibraryCardNumber = StandardProcess(LibraryCardNumber, value);
    }
    
    
    private String CardExpiry;
    @VerifyAnnotation(ApplicationName="Card Expiry", DBName="CardExpiry",  Type=TypeEnum.DATE, Length=50, Editable=false)
    public String CardExpiry(String value)
    {
        return CardExpiry = StandardProcess(CardExpiry, value);
    }
    
    
    private String IdentityNumber;
    @VerifyAnnotation(ApplicationName="Identity Number", DBName="IdentityNumber",  Type=TypeEnum.NUMERICSTRING, Length=8, ExactLength=true, PrimaryKey=true)
    public String IdentityNumber(String value)
    {
        return IdentityNumber = StandardProcess(IdentityNumber, value);
    }
    
    
    private String Password;
    @VerifyAnnotation(ApplicationName="Password", DBName="Password",  Type=TypeEnum.STRING, Length=32)
    public String Password(String value)
    {
        return Password = StandardProcess(Password, value);
    }
    
    
    private String Email;
    @VerifyAnnotation(ApplicationName="E-mail", DBName="Email",  Type=TypeEnum.STRING, Length=250)
    public String Email(String value)
    {
        return Email = StandardProcess(Email, value);
    }
    
    
    private String Name;
    @VerifyAnnotation(ApplicationName="Prefered Name", DBName="Name",  Type=TypeEnum.STRING, Length=50)
    public String Name(String value)
    {
        return Name = StandardProcess(Name, value);
    }
    
    
    private String PhoneNumber;
    @VerifyAnnotation(ApplicationName="Phone #", DBName="PhoneNumber",  Type=TypeEnum.PHONE, Length=20)
    public String PhoneNumber(String value)
    {
        return PhoneNumber = StandardProcess(PhoneNumber, value);
    }
    
    
    private String Type;
    @VerifyAnnotation(ApplicationName="Member Type", DBName="Type",  Type=TypeEnum.LOOKUP, Length=20, LookupDBTable="MemberType", LookupDBField="Type")
    public String Type(String value)
    {
        return Type = StandardProcess(Type, value);
    }
    
    
    private String JoinDate;
    @VerifyAnnotation(ApplicationName="Join Date", DBName="JoinDate",  Type=TypeEnum.DATE, Length=50, Editable=false)
    public String JoinDate(String value)
    {
        return JoinDate = StandardProcess(JoinDate, value);
    }
    
    public boolean LoggedIn()
    {
        boolean Is = this.GetVerifiedStatus();
        return Is;
    }
    
    public boolean IsNonmember()
    {
        boolean Is = Type.equalsIgnoreCase("nonmember");
        return Is;
    }
    public boolean IsStudent()
    {
        boolean Is = Type.equalsIgnoreCase("student");
        return Is;
    }
    public boolean IsFaculty()
    {
        boolean Is = Type.equalsIgnoreCase("faculty");
        return Is;
    }
    public boolean IsLibrarian()
    {
        boolean Is = Type.equalsIgnoreCase("librarian");
        return Is;
    }
    
    
    @Override
    public String toString()
    {
        return "Card# " + LibraryCardNumber + " perfered name " + Name;
    }
    
    public double GetTotalFine()
    {
        ArrayList<VerifiableObject> VOList = this.GetRelatedData(CheckOut.class, 9999);
        
        double FineCount = 0;
        for(VerifiableObject VO: VOList)
        {
            CheckOut CO = (CheckOut)VO;
            double Late = GetNumber(CO.LateFine(null));
            double Condition = GetNumber(CO.CopyConditionFine(null));
            double Payment = GetNumber(CO.Payment(null));
            FineCount += (Late + Condition - Payment);
        }
        
        if (FineCount < 0.01)
            return 0;
        else
            return FineCount;
    }
}
